package gee

import (
	"fmt"
	"log"
	"net/http"
	"runtime"
	"strings"
	"time"
)

func Logger() HandleFunc {
	return func(c *Context) {
		// Start timer
		t := time.Now()
		// Process request
		c.Next()
		// Calculate resolution time
		log.Printf("[%d] %s in %v", c.StatusCode, c.Req.RequestURI, time.Since(t))
	}
}

//该函数用作附加上出错的栈信息，以方便定位。
func trace(message string) string {
	var pc [32]uintptr
	//Callers该函数必须要用已经实例化，有具体长度的指针切片，否则不会正常返回结果。
	n := runtime.Callers(3, pc[:])
	var build strings.Builder
	build.WriteString(message)
	build.WriteString("\nTraceBacke:")
	for i := 0; i < n; i++ {
		fileName, line := runtime.FuncForPC(pc[i]).FileLine(pc[i])
		build.WriteString(fmt.Sprintf("\n\t%s:%d", fileName, line))
	}
	return build.String()
}

func Revcover() HandleFunc {
	return func(c *Context) {
		defer func() {
			if err := recover(); err != nil {
				result := trace(fmt.Sprintf("%v", err))
				log.Println(result)
				c.String(http.StatusInternalServerError, "Internal Server Error")
			}
		}()
		//这个中间件用来
		c.Next()
	}
}
